package cn.yilongquan.service.impl;

import cn.yilongquan.mapper.MenuMapper;
import cn.yilongquan.user.query.MenuQuery;
import cn.yilongquan.service.MenuService;
import cn.yilongquan.user.domain.Menu;
import cn.yilongquan.util.CustomPageResult;
import cn.yilongquan.util.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 菜单服务实现类
 */
@Service
public class MenuServiceImpl implements MenuService {

    @Autowired
    private MenuMapper menuMapper;

    @Override
    public Menu findById(Long id) {
        return menuMapper.findById(id);
    }

    @Override
    public List<Menu> findAll() {
        return menuMapper.findAll();
    }

    @Override
    @Transactional
    public void add(Menu menu) {
        menuMapper.add(menu);
    }

    @Override
    @Transactional
    public void update(Menu menu) {
        menuMapper.update(menu);
    }

    @Override
    @Transactional
    public void deleteById(Long id) {
        // 检查是否有子菜单
        if (hasChildren(id)) {
            throw new RuntimeException("该菜单存在子菜单，不能删除");
        }
        menuMapper.deleteById(id);
    }

    @Override
    @Transactional
    public void batchDelete(List<Long> ids) {
        // 检查是否有子菜单
        for (Long id : ids) {
            if (hasChildren(id)) {
                throw new RuntimeException("ID为" + id + "的菜单存在子菜单，不能删除");
            }
        }
        menuMapper.batchDelete(ids);
    }

    @Override
    public R pageList(MenuQuery menuQuery) {
        // 计算偏移量
        Integer page = menuQuery.getPage();
        Integer size = menuQuery.getSize();
        menuQuery.setOffset((page - 1) * size);
        // 1. 查询总记录数
        Long total = menuMapper.count(menuQuery);

        // 2. 查询当前页数据
        List<Menu> rows = menuMapper.pageList(menuQuery);

        // 3. 构建自定义分页结果（传入总记录数、当前页数据、当前页码、每页条数）
        CustomPageResult<Menu> pageResult = new CustomPageResult<>(
                total,
                rows,
                menuQuery.getPage(),  // 获取当前页码
                menuQuery.getSize()   // 获取每页条数
        );

        // 4. 用R包装后返回
        return R.ok(pageResult);
    }

    @Override
    public R getTree() {
        // 获取所有菜单
        List<Menu> allMenus = menuMapper.findMenuTree();
        // 构建树形结构
        List<Menu> tree = buildTree(allMenus, null);
        return R.ok(tree);
    }

    /**
     * 构建树形结构
     */
    private List<Menu> buildTree(List<Menu> allMenus, Long parentId) {
        return allMenus.stream()
                .filter(menu -> {
                    // 一级菜单的parentId为null或0
                    if (parentId == null) {
                        return menu.getParentId() == null || menu.getParentId() == 0;
                    }
                    return parentId.equals(menu.getParentId());
                })
                .map(menu -> {
                    // 递归设置子菜单
                    menu.setChildren(buildTree(allMenus, menu.getId()));
                    return menu;
                })
                .collect(Collectors.toList());
    }

    @Override
    public boolean hasChildren(Long id) {
        List<Menu> allMenus = menuMapper.findAll();
        return allMenus.stream().anyMatch(menu -> id.equals(menu.getParentId()));
    }
}
